package com.yngrp.service.impl.wo;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.jeecgframework.core.common.service.impl.CommonServiceImpl;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.web.system.pojo.base.TSDepart;
import org.jeecgframework.web.system.pojo.base.TSType;
import org.jeecgframework.web.system.pojo.base.TSUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yngrp.entity.Holiday;
import com.yngrp.entity.Role2WoState;
import com.yngrp.entity.TodoWO;
import com.yngrp.entity.WoType;
import com.yngrp.entity.WorkAsso;
import com.yngrp.entity.WorkOrder;
import com.yngrp.entity.WorkProcess;
import com.yngrp.service.wo.WorkOrderService;
import com.yngrp.util.Constant;

/**
 *  @Description: 工单处理业务接口实现类
 *  @author  SLH
 *  @date  20160716 
 *
 */
@Service("workOrderService")
@Transactional
public class WorkOrderServiceImpl extends CommonServiceImpl implements WorkOrderService {

	/**
	 * 创建新工单
	 */
	@Override
	public void saveWO(WorkOrder wo) {
		// TODO Auto-generated method stub
		wo.setCustomerNo(wo.getCustomerNo().trim());
		wo.setCustomerName(wo.getCustomerName().trim());
		wo.setContactMan(wo.getContactMan().trim());
		wo.setContactAddress(wo.getContactAddress().trim());
		wo.setContactPhone(wo.getContactPhone().trim());
		wo.setContactPhone2(wo.getContactPhone2().trim());
		
		TSUser user = ResourceUtil.getSessionUserName();
		
		String woTypeName = getTypeName(wo.getWoType()).getTypeName();
		wo.setWoTypeDesc(woTypeName);
		wo.setWoStateDesc(getNameByTypeCode(Constant.WOSTATE,wo.getWoState()));
		wo.setWoSrcDesc(getTypeName(wo.getWoType()).getPlatform());
		
		wo.setCreateBy(user.getId());
		wo.setCreateRealname(user.getRealName());
		//wo.setDoUsername(user.getRealName());
		wo.setCreateDepartmentid(user.getCurrentDepart().getId());
		wo.setCreateDepartmentname(user.getCurrentDepart().getDepartname());
		wo.setCreateDatetime(new Date());
		
		//保存工单信息
		this.commonDao.save(wo);
		//保存关联工单信息
		if(StringUtils.isNotEmpty(wo.getWoAssos())){
			this.saveAssoWO(wo.getId().toString(),wo.getWoAssos());
		}
		
		//保存工单处理意见
		this.saveWoProcess(wo, user);
		
		//提交坐席管理员审核
		if(wo.getWoState().equals(Constant.S02)){
			this.saveTodoWO(wo,user,user.getCurrentDepart().getId(),user.getCurrentDepart().getDepartname());
		}else if(wo.getWoState().equals(Constant.S03)){ //派发到班组
			//主办部门ID
			this.saveProcessDepart(wo.getzOrgIds(),wo,user);
			//协办部门ID			 
			this.saveProcessDepart(wo.getxOrgIds(),wo,user);
				
		}
	}
	
	/**
	 * 根据工单类型编码获取工单类型名称
	 * @param woTypeCode
	 * @return
	 */
	private WoType getTypeName(String woTypeCode){
		WoType woType = this.commonDao.findUniqueByProperty(WoType.class, "typeCode", woTypeCode);

		return woType;
	}
	
	/**
	 * 删除工单
	 * @param wo
	 */
	public void delWO(Integer wo_id){
		 
		this.commonDao.executeHql("delete from WorkProcess where workOrder.id = "+wo_id);
		this.commonDao.executeHql("delete from TodoWO where workOrder.id = "+wo_id);
		this.commonDao.executeHql("delete from WorkAsso where mainWoid = "+wo_id);
		this.commonDao.executeHql("delete from WorkOrder where id = "+wo_id);
	}
	
	
	
	/**
	 * 根据字典组别获取子项集合
	 * @param groupCode
	 * @return
	 */
	public List<TSType> getTsTypeByGroupName(String groupCode){
		
		List<TSType> ls = this.commonDao.findHql("from TSType where TSTypegroup.typegroupcode = ?",groupCode);
		return ls;
	}
	
	/**
	 * 保存工单处理信息
	 */
	private void saveWoProcess(WorkOrder wo,TSUser user){
		WorkProcess wp = new WorkProcess();
		if(StringUtils.isNotBlank(wo.getProcessId())){
			wp = this.commonDao.get(WorkProcess.class, wo.getProcessId());
		}
				
		wp.setIsCheck(wo.getIsCheck());
		wp.setWorkOrder(wo);
		wp.setWoOpinion(wo.getWoOpinion());
		wp.setWoOperation(wo.getWoState());
		wp.setWoOperadesc(getNameByTypeCode(Constant.WOSTATE,wo.getWoState()));
		wp.setSaveState(wo.getSaveState());
		wp.setProcessType(wo.getProcessType());
		wp.setProcessCustomerNo(wo.getProcessCustomerNo());
		wp.setResponer(wo.getResponer());
		
		wp.setCreateBy(user.getId());
		wp.setCreateRealname(user.getRealName());
		wp.setCreateDepartmentid(user.getCurrentDepart().getId());
		wp.setCreateDepartmentname(user.getCurrentDepart().getDepartname());
		wp.setCreateDatetime(new Date());
		
		//工单处理用时计算
		String todo_id = wo.getTodoId();
		Long useHours = 1l;
		if(StringUtils.isNotEmpty(todo_id)){
			TodoWO todo = this.commonDao.get(TodoWO.class, todo_id);
			Date todoDate = todo.getCreateDatetime();
			Long useMill = new Date().getTime() - todoDate.getTime();
			//耗时
			useHours = useMill / (1000 * 60 * 60 );
		}
		wp.setUseHours(useHours.toString());
		
		this.commonDao.saveOrUpdate(wp);
	}
	
	/**
	 * 提交到部门审核
	 */
	private void saveTodoWO(WorkOrder wo,TSUser user,String deptId,String deptName){
		
		saveTodo(wo,null,null,deptId, deptName,user.getId(),user.getRealName(),
				           user.getCurrentDepart().getId(),user.getCurrentDepart().getDepartname());
		
	}
	
	/**
	 * 保存待办工单信息
	 * @param wo
	 * @param acUserId
	 * @param acUserName
	 * @param acDeptId
	 * @param acDeptName
	 * @param createBy
	 * @param createRealname
	 * @param createDepartmentid
	 * @param createDepartmentname
	 */
	private void saveTodo(WorkOrder wo,String acUserId,String acUserName,String acDeptId,String acDeptName,
			String createBy,String createRealname,String createDepartmentid,String createDepartmentname){
        TodoWO td = new TodoWO();
		
		td.setWorkOrder(wo);
		td.setAcUserid(acUserId);
		td.setAcUsername(acUserName);
		td.setAcDeptid(acDeptId);
		td.setAcDeptname(acDeptName);		
		
		td.setCreateBy(createBy);
		td.setCreateRealname(createRealname);
		td.setCreateDepartmentid(createDepartmentid);
		td.setCreateDepartmentname(createDepartmentname);
		td.setCreateDatetime(new Date());
		
		//初始状态：未读
		td.setIsRead(Constant.WO_ISREAD_0);
		
		this.commonDao.save(td);
	}
	
	/**
	 * 处理待办工单
	 */
	@Override
	public void saveProcessWO(WorkOrder wo) {
		// TODO Auto-generated method stub
		try{
			TSUser user = ResourceUtil.getSessionUserName();
			
			//更新工单受理内容(班组人员不能更新) 
			if(!user.getRoleCodes().contains(Constant.TEAM_ROLE_CODE)){
				WorkOrder woContent =  this.commonDao.getEntity(WorkOrder.class, wo.getId());
				woContent.setWoContent(wo.getWoContent()); 
				this.commonDao.updateEntitie(woContent);
			}
			
			//保存工单处理信息
			this.saveWoProcess(wo, user);
			
			if(wo.getSaveState().equals("0")){
				//如果是临时保存，只保存意见信息
				return;
			}
			
			//派发部门处理
			if(wo.getWoState().equals(Constant.S03)){
				//主办部门ID
				saveProcessDepart(wo.getzOrgIds(),wo,user);
				//协办部门ID			 
				saveProcessDepart(wo.getxOrgIds(),wo,user);
				
				//如果是坐席管理员下派工单，重新保存处理时限
				if(user.getRoleCodes().equals(Constant.SEAT_ROLE_MGR_CODE)){
					WorkOrder worder =  this.commonDao.get(WorkOrder.class, wo.getId());
					worder.setOverTime(callOverTime(worder.getWoType()));
					this.commonDao.updateEntitie(worder);
				}
				
			}else if(wo.getWoState().equals(Constant.S04)||wo.getWoState().equals(Constant.S02)){//退单或部门提交审核
				TodoWO todoWO = this.commonDao.get(TodoWO.class, wo.getTodoId());
				
				saveTodo(todoWO.getWorkOrder(),todoWO.getCreateBy(),todoWO.getCreateRealname(),todoWO.getCreateDepartmentid(), todoWO.getCreateDepartmentname(),
						    user.getId(),user.getRealName(),user.getCurrentDepart().getId(),user.getCurrentDepart().getDepartname());
			}else if(wo.getWoState().equals(Constant.S00)){//归档
				//删除该工单的所有待办工单
				removeTodoWoByWoid(wo.getId());
			}
			
			//删除待办工单
			if(StringUtils.isNotEmpty(wo.getTodoId())){
				String exeSql = "delete from TodoWO where id='"+wo.getTodoId()+"'";
				this.commonDao.executeHql(exeSql);
			}
			
			//更新工单状态及处理人信息
			updateWoState(wo.getId(),wo.getWoState());
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	/**
	 * 更新工单状态及处理人信息
	 * @param wo_id
	 * @param woState
	 */
	private void updateWoState(Long wo_id,String woState){
		TSUser user = ResourceUtil.getSessionUserName();
		WorkOrder wo = this.commonDao.getEntity(WorkOrder.class, wo_id);
		wo.setWoState(woState);
		wo.setWoStateDesc(getNameByTypeCode(Constant.WOSTATE,woState));
		//如果是班组人员处理
		if(user.getRoleCodes().contains(Constant.TEAM_ROLE_CODE)){
			wo.setDoUsername(user.getRealName());
		}
		this.commonDao.updateEntitie(wo);
	}
	
	/**
	 * 根据工单ID删除所有待办工单
	 * @param wo_id
	 */
	private void removeTodoWoByWoid(Long wo_id){
		
		String exeSql = "delete from TodoWO where workOrder.id="+wo_id;
		this.commonDao.executeHql(exeSql);
	}
	
	//提交到部门管理员，保存部门ID为待办 
	private void saveProcessDepart(String deptIds,WorkOrder wo,TSUser user){
		if(StringUtils.isNotEmpty(deptIds)){
			 String[] orgIdsArray = deptIds.split(",");
			 for(int i=0;i<orgIdsArray.length;i++){
				 String deptId = orgIdsArray[i];
				 if(StringUtils.isNotEmpty(deptId)){
					 TSDepart depart = this.commonDao.getEntity(TSDepart.class, deptId);
					 
					 this.saveTodoWO(wo,user,deptId,depart.getDepartname());					
				 }
			 }
		 }
	}
	
	/**
	 * 根据角色编码获取工单状态 
	 * @param roleCode
	 * @return
	 */
	public List<Role2WoState> getWoStateByRole(String roleCode){
		List<Role2WoState> rwList = new ArrayList<Role2WoState>();
		StringBuffer querySql = new StringBuffer();
		querySql.append("SELECT m.typename typename,t.wostate_code wostate_code FROM yl_role_wostate t , t_s_type m,t_s_typegroup n ");
		querySql.append(" WHERE t.wostate_code = m.typecode ");
		querySql.append(" AND m.typegroupid = n.id AND n.typegroupcode = '"+Constant.WOSTATE+"' ");
		querySql.append(" AND t.role_code=? ORDER BY sort_no");
		
		
		List<Map<String,Object>> list = this.commonDao.findForJdbc(querySql.toString(), roleCode);
		
		Role2WoState rwo = null;
		for(Map<String,Object> m: list){
			rwo = new Role2WoState();
			
			rwo.setWoStateCode(m.get("wostate_code").toString());
			rwo.setWoStateDesc(m.get("typename").toString());
			rwList.add(rwo);
		}
		
		return rwList;
	}
	
	/**
	 * 保存关联工单
	 * @param wo
	 */
	public void saveAssoWO(String mainWoid,String asWoids){
		//先删除已关联的工单
		String exeSql = "delete from WorkAsso where mainWoid="+mainWoid;
		this.commonDao.executeHql(exeSql);
		
		//再插入新关联的工单
		String[] asWoidArr = asWoids.split(",");
		WorkAsso wa = null;
		for(int i=0;i<asWoidArr.length;i++){
			if(StringUtils.isNotEmpty(asWoidArr[i])){
				wa = new WorkAsso();
				wa.setMainWoid(Long.parseLong(mainWoid));
				wa.setAssoWoid(Long.parseLong(asWoidArr[i]));
				
				this.commonDao.save(wa);
			}
		}
		
	}
	
	/**
	 * 根据工单类型计算工单办结截止时间
	 * @param typeCode
	 */
	public String callOverTime(String typeCode){
		String overDate_Str = "";
		if(StringUtils.isNotBlank(typeCode)){
			WoType woType = this.commonDao.findUniqueByProperty(WoType.class, "typeCode", typeCode);
			String overTimeType = woType.getOverTimeType();
			int overTimeVal = woType.getOverTimeVal();
	
			//初始化节假日
			List<Calendar> holidayList = initHoliday();

			//截止时间 
			Calendar overCalendar = Calendar.getInstance();
			//当前时间 
			Calendar calendar = Calendar.getInstance();
			
			if(overTimeType.equals(Constant.OVERTIME_TYPE_DAY)){
				overCalendar = Constant.addDateByWorkDay(calendar,overTimeVal,holidayList);
				
			}else if(overTimeType.equals(Constant.OVERTIME_TYPE_HOUR)){
				overCalendar = Constant.addHourByWorkHour(calendar,overTimeVal,holidayList);
			}
			
			SimpleDateFormat sdf=new SimpleDateFormat(Constant.OVERTIME_DATE_FMT);
			sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
			overDate_Str = sdf.format(overCalendar.getTime());
			
		}
		
		return overDate_Str;
	}
	
	//初始化最近30天的节假日
	private List<Calendar> initHoliday(){
		List<Calendar> holidayList = new ArrayList<Calendar>();
		Date now = new Date();
		String startDate = DateUtil.formatDate(now, "yyyy-MM-dd");
		String endDate = DateUtil.formatDate(DateUtils.addDays(now, 30), "yyyy-MM-dd");
		
		List<Holiday> hLst = this.commonDao.findHql("from Holiday where hDate between ? and ?", startDate,endDate);
		for(Holiday holiday:hLst){
			
			Constant.addHolidayList(holiday.gethDate(), holidayList);	        
		}
		return holidayList;
	}

}
